package com.qingcloud.adminbackend.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.ImmutableMap;
import com.qingcloud.adminbackend.base.ZTreeBo;
import com.qingcloud.adminbackend.entity.role.SysRole;
import com.qingcloud.adminbackend.entity.sysfunction.*;
import com.qingcloud.adminbackend.entity.sysorder.SysOrder;
import com.qingcloud.adminbackend.entity.sysorder.SysOrderFunction;
import com.qingcloud.adminbackend.entity.sysorg.SysOrg;
import com.qingcloud.adminbackend.entity.sysorg.SysOrgLogoDTO;
import com.qingcloud.adminbackend.entity.sysorg.SysUserOrg;
import com.qingcloud.adminbackend.entity.user.SysUser;
import com.qingcloud.adminbackend.entity.userrole.UserRoleVO;
import com.qingcloud.adminbackend.mapper.*;
import com.qingcloud.adminbackend.service.ISysFunctionService;
import com.qingcloud.adminbackend.service.ISysUserService;
import com.qingcloud.adminbackend.utils.DateUtil;
import com.qingcloud.base.remote.pojo.LoginUserDTO;
import com.qingcloud.base.remote.pojo.MenuDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统功能表 服务实现类
 * </p>
 *
 * @author liyuhong
 * @since 2018-11-16
 */
@Service
public class SysFunctionServiceImpl extends ServiceImpl<SysFunctionMapper, SysFunction> implements ISysFunctionService {

    Logger logger = LoggerFactory.getLogger(SysFunctionServiceImpl.class);
    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysFunctionMapper sysFunctionMapper;

    @Resource
    private SysRoleFunctionMapper sysRoleFunctionMapper;

    @Resource
    private SysOrgFunctionMapper sysOrgFunctionMapper;

    @Resource
    private SysUserRoleMapper sysUserRoleMapper;

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserFunctionMapper sysUserFunctionMapper;

    @Resource
    private SysUserOrgMapper sysUserOrgMapper;

    @Resource
    private SysOrderMapper sysOrderMapper;

    @Resource
    private SysOrderFunctionMapper sysOrderFunctionMapper;

    @Resource
    private SysOrgMapper sysOrgMapper;

    @Resource
    private ISysUserService sysUserService;

    private MenuDTO buildFromSysFunction(SysFunction sysFunction) {
        MenuDTO it = new MenuDTO();
        it.setId(sysFunction.getId());
        it.setParentId(sysFunction.getParentId());
        it.setMenuName(sysFunction.getFunctionName());
        it.setMenuNameEn(sysFunction.getFunctionNameEn());
        it.setMenuUrl(sysFunction.getFunctionUrl());
        it.setOrderNo(sysFunction.getOrderNo());
        it.setIcon(sysFunction.getIcon());
        it.setMenuType(sysFunction.getMenuType());
        it.setCode(sysFunction.getCode());
        it.setHaveChildren(false);
        it.setRoleFlag(sysFunction.getRoleFlag());
        return it;
    }

    /**
     * 获取功能权限
     *
     * @param isAdmin 判断是否为admin
     * @return sysFunctionDTO
     */
    @Override
    public List<MenuDTO> getFunctionByUserId(boolean isAdmin, SysFunctionDTO sysFunctionDTO) {
        List<SysFunction> sysFunctionDTOList = sysFunctionMapper.getFunctionByUserId(isAdmin, sysFunctionDTO);
        //找到所有的菜单
        List<MenuDTO> allMenuList =
                sysFunctionDTOList.stream().map(it -> {
                    final MenuDTO menuDTO = this.buildFromSysFunction(it);
                    menuDTO.setMenuUrl("javascript:void(0)");
                    return menuDTO;
                }).collect(Collectors.toList());
        //按父菜单分类
        Map<String, List<MenuDTO>> funcMap =
                allMenuList.stream().filter(it -> it.getParentId() != null).collect(Collectors.groupingBy(MenuDTO::getParentId));
        //有子菜单的设置子菜单
        allMenuList.stream().filter(it -> funcMap.containsKey(it.getId())).forEach(it -> {
            it.setHaveChildren(true);
            it.setChildList(funcMap.get(it.getId()).stream().sorted(Comparator.comparing(MenuDTO::getOrderNo)).collect(Collectors.toList()));
        });
        //将第一级菜单返回
        List<MenuDTO> menuDTOList =
                allMenuList.stream().filter(it -> StringUtils.isEmpty(it.getParentId())).sorted(Comparator.comparing(MenuDTO::getOrderNo)).collect(Collectors.toList());
        return menuDTOList;
    }

    /**
     * 获取所有的菜单权限(菜单树)
     *
     * @param menuType
     * @param userId
     * @return
     */
    @Override
    public Map<String, Object> getFunctionByUserId(String menuType, Integer urlFlag, String userId) {

        List<SysFunction> functions = getAllFunction(menuType, userId, false);
        //排序
        if (!CollectionUtils.isEmpty(functions)) {
            functions = functions.stream().sorted(Comparator.comparing(SysFunction::getOrderNo)).collect(Collectors.toList());
        }
        return getMenuDTOSToMap(urlFlag, functions);
    }

    /**
     * 查询展示模块
     * 1:网格化菜单；2：健康云菜单 下的所有模块
     *
     * @param menuTypes
     * @return
     */
    @Override
    public List<ModuleDTO> getModuleByUserId(String menuTypes) {
        List<String> typeList = Arrays.asList(menuTypes.split(","));
        return sysFunctionMapper.getModuleByUserId(typeList);
    }

    /**
     * 查询选中功能
     *
     * @param menuBO
     * @return
     */
    @Override
    public Set<String> getFunctionByMenuBO(MenuBO menuBO) {
        Set<String> set = new HashSet<>();
        Set<String> mfunctionIds = sysFunctionMapper.getFunctionByModuleId(menuBO.getModuleIds());
        for (String functionId : mfunctionIds) {
            set.add(functionId);
        }
        Set<String> ofunctionIds = sysFunctionMapper.getFunctionByOrgId(menuBO.getOrgId());
        for (String functionId : ofunctionIds) {
            set.add(functionId);
        }
        return set;
    }

    /**
     * 新增用户授权功能列表
     *
     * @param roleId
     * @param userId
     * @param menuType
     * @return
     */
    @Override
    public InitFunctionTreeDTO getUserAuthFunctions(List<String> roleId, List<String> orgIds, String userId,
                                                    String menuType, Boolean isAdmin) {
        //查询用户身份对应的功能,不能被选择
        QueryWrapper<SysRoleFunction> roleFunQuery = new QueryWrapper<>();
        roleFunQuery.in("role_id", roleId);
        List<SysRoleFunction> sysRoleFunctions = sysRoleFunctionMapper.selectList(roleFunQuery);
        Set<String> oriFunIds = new HashSet<>();
        sysRoleFunctions.forEach(e -> oriFunIds.add(e.getFunctionId()));
        Set<String> userOrgFunIds = new HashSet<>();
        QueryWrapper<SysFunction> funQuery = new QueryWrapper<>();
        InitFunctionTreeDTO result = new InitFunctionTreeDTO();
        List<SysFunction> sysFunctions;
        if (!CollectionUtils.isEmpty(orgIds)) {
            //查询用户所属组织对应的功能
            List<SysOrgFunction> sysOrgFunctions = new ArrayList<>();
            List<SysOrderFunction> sysOrderFunctions = new ArrayList<>();
            orgIds.forEach(orgId -> {
                SysOrg sysOrg = sysOrgMapper.selectById(orgId);
                if (sysOrg.getCategory() == 1) {
                    //客户（查询订单的功能）
                    //查询客户下的订单
                    QueryWrapper<SysOrder> orderQueryWrapper = new QueryWrapper<>();
                    orderQueryWrapper.eq("org_id", orgId);
                    List<SysOrder> sysOrders = sysOrderMapper.selectList(orderQueryWrapper);
                    if (!CollectionUtils.isEmpty(sysOrders)) {
                        List<String> orderIds = new ArrayList<>();
                        sysOrders.forEach(e -> orderIds.add(e.getId()));
                        //查询订单的功能
                        QueryWrapper<SysOrderFunction> orderFunQuery = new QueryWrapper<>();
                        orderFunQuery.in("order_id", orderIds);
                        sysOrderFunctions.addAll(sysOrderFunctionMapper.selectList(orderFunQuery));
                    }
                } else {
                    //分支机构（查询客户功能）
                    QueryWrapper<SysOrgFunction> orgFunQuery = new QueryWrapper<>();
                    orgFunQuery.eq("org_id", orgId);
                    sysOrgFunctions.addAll(sysOrgFunctionMapper.selectList(orgFunQuery));
                }
            });
            sysOrgFunctions.forEach(e -> userOrgFunIds.add(e.getFunctionId()));
            sysOrderFunctions.forEach(e -> userOrgFunIds.add(e.getFunctionId()));
            if (CollectionUtils.isEmpty(userOrgFunIds)) {
                return result;
            }
            funQuery.in("id", userOrgFunIds);
            funQuery.eq("delete_flag", 0);
            funQuery.eq("menu_type", menuType);
            funQuery.orderByAsc("function_level, order_no");
            sysFunctions = sysFunctionMapper.selectList(funQuery);
        } else {
            //蛙鸣用户-->此页面在配置时，当前登录用户的全部可用功能作为菜单树的全部
            // （update【2019-01-23】:登录用户从其他地方获取的功能加上被赋权用户通过身份获得的功能【disable】），
            // 被授权用户通过身份获得的功能选中但是disable。
            //当前登录用户的可用功能
            SysUser sysUser = sysUserMapper.selectById(userId);
            //判断是否是完全管理员
            Integer adminFlag = sysUser.getAdminFlag();
            Set<String> longinUserFunIds = new HashSet<>();
            if (isAdmin || adminFlag == 1) {
                //超级管理员。可用所有功能
                List<SysFunction> adminFunctions = sysFunctionMapper.selectByMap(ImmutableMap.of("menu_type", menuType, "delete_flag", 0));
                adminFunctions.forEach(e -> longinUserFunIds.add(e.getId()));
            } else {
                //外额外赋予给他的功能 userfunction
                List<SysUserFunction> functions = sysUserFunctionMapper.selectByMap(ImmutableMap.of("user_id", userId));
                functions.forEach(e -> longinUserFunIds.add(e.getFunctionId()));
            }
            if (CollectionUtils.isEmpty(oriFunIds) && CollectionUtils.isEmpty(longinUserFunIds)) {
                return result;
            }
            //自己本身身份对应的功能
            longinUserFunIds.addAll(oriFunIds);
            funQuery.in("id", longinUserFunIds);
            funQuery.eq("delete_flag", 0);
            funQuery.eq("menu_type", menuType);
            funQuery.orderByAsc("function_level, order_no");
            sysFunctions = sysFunctionMapper.selectList(funQuery);
        }
        if (CollectionUtils.isEmpty(oriFunIds)) {
            sysFunctions.forEach(fun -> fun.setRoleFlag(0));
        } else {
            //表示不能被选的节点
            sysFunctions.forEach(fun -> {
                fun.setRoleFlag(0);
                if (oriFunIds.contains(fun.getId())) {
                    fun.setRoleFlag(1);
                } else {
                    fun.setRoleFlag(0);
                }
            });
        }
        //获取身份预设的功能
        Map<String, List<String>> originalFunctionIds = new HashMap<>();
        Map<String, List<SysRoleFunction>> tempMap = sysRoleFunctions.stream().collect(Collectors.groupingBy(SysRoleFunction::getRoleId));
        tempMap.keySet().forEach(key -> {
            List<SysRoleFunction> temp = tempMap.get(key);
            List<String> functionIds = temp.stream().map(SysRoleFunction::getFunctionId).collect(Collectors.toList());
            originalFunctionIds.put(key, functionIds);
        });
        result.setFunctionTree(functionTree(sysFunctions));
        result.setOriginalFunctionIds(originalFunctionIds);
        return result;
    }

    /**
     * 获取有权限的所有功能列表
     *
     * @param userId
     * @param menuType
     * @return
     */
    private List<SysFunction> getSysFunctions(String userId, Integer menuType, boolean isAllFunc) {
        List<UserRoleVO> roleByUserId = sysUserRoleMapper.findRoleByUserId(userId);
        List<String> roleIds = new ArrayList<>();
        roleByUserId.forEach(e -> roleIds.add(String.valueOf(e.getId())));
        if (CollectionUtils.isEmpty(roleIds)) {
            return Collections.emptyList();
        }
        //用户身份对应的功能
        QueryWrapper<SysRoleFunction> roleFunctionQueryWrapper = new QueryWrapper<>();
        roleFunctionQueryWrapper.in("role_id", roleIds);
        List<SysRoleFunction> sysRoleFunctions = sysRoleFunctionMapper.selectList(roleFunctionQueryWrapper);
        Set<String> roleFunctionSet = new HashSet<>();
        sysRoleFunctions.forEach(e -> roleFunctionSet.add(e.getFunctionId()));
        //附加功能
        QueryWrapper<SysUserFunction> userFunctionQueryWrapper = new QueryWrapper<>();
        userFunctionQueryWrapper.eq("user_id", userId);
        List<SysUserFunction> sysUserFunctions = sysUserFunctionMapper.selectList(userFunctionQueryWrapper);
        Set<String> addFunctionSet = new HashSet<>();
        sysUserFunctions.forEach(e -> addFunctionSet.add(e.getFunctionId()));
        //并集
        roleFunctionSet.addAll(addFunctionSet);
        if (menuType == 1) {
            //用户所属客户
            List<SysUserOrg> userOrgs = sysUserOrgMapper.selectByMap(ImmutableMap.of("user_id", userId));
            if (!CollectionUtils.isEmpty(userOrgs)) {
                List<String> orgIds = new ArrayList<>();
                userOrgs.forEach(e -> orgIds.add(e.getOrgId()));
                QueryWrapper<SysOrgFunction> orgFunctionQueryWrapper = new QueryWrapper<>();
                orgFunctionQueryWrapper.in("org_id", orgIds);
                List<SysOrgFunction> sysOrgFunctions = sysOrgFunctionMapper.selectList(orgFunctionQueryWrapper);
                //客户下订单有的功能
                QueryWrapper<SysOrder> orderQueryWrapper = new QueryWrapper<>();
                orderQueryWrapper.in("org_id", orgIds);
                List<SysOrder> sysOrders = sysOrderMapper.selectList(orderQueryWrapper);
                List<SysOrderFunction> sysOrderFunctions = Collections.emptyList();
                if (!CollectionUtils.isEmpty(sysOrders)) {
                    List<String> orderIds = new ArrayList<>();
                    sysOrders.forEach(e -> orderIds.add(e.getId()));
                    //查询订单的功能
                    QueryWrapper<SysOrderFunction> orderFunQuery = new QueryWrapper<>();
                    orderFunQuery.in("order_id", orderIds);
                    sysOrderFunctions = sysOrderFunctionMapper.selectList(orderFunQuery);
                }
                Set<String> orgFunctionSet = new HashSet<>();
                sysOrgFunctions.forEach(e -> orgFunctionSet.add(e.getFunctionId()));
                sysOrderFunctions.forEach(e -> orgFunctionSet.add(e.getFunctionId()));
                //交集
                roleFunctionSet.retainAll(orgFunctionSet);
            }
        }
        if (CollUtil.isEmpty(roleFunctionSet)) {
            return Collections.emptyList();
        }
        //所有可用的功能
        QueryWrapper<SysFunction> functionQueryWrapper = new QueryWrapper<>();
        functionQueryWrapper.in("id", roleFunctionSet);
        functionQueryWrapper.eq("delete_flag", 0);
        functionQueryWrapper.eq("menu_type", menuType);
        List<Integer> funcTypeId = Arrays.asList(1, 2);
        if (!isAllFunc) {
            functionQueryWrapper.in("function_type", funcTypeId);
        }
        functionQueryWrapper.orderByAsc("function_level, order_no");
        List<SysFunction> sysFunctions = baseMapper.selectList(functionQueryWrapper);
        return sysFunctions;
    }

    private List<MenuDTO> functionTree(List<SysFunction> funs) {
        List<MenuDTO> menuDTOS = new ArrayList<>();
        funs.forEach(fun -> {
            menuDTOS.add(this.buildFromSysFunction(fun));
        });
        //所有顶级节点
        List<MenuDTO> parent = new ArrayList<>();
        List<MenuDTO> child = new ArrayList<>();
        menuDTOS.forEach(fun -> {
            if (StringUtils.isEmpty(fun.getParentId())) {
                parent.add(fun);
            } else {
                child.add(fun);
            }
        });
        List<MenuDTO> result = new ArrayList<>();
        parent.forEach(pa -> {
            result.add(recursionChildren(pa, child));
        });
        return result;
    }

    private MenuDTO recursionChildren(MenuDTO functionVO, List<MenuDTO> list) {
        /*如果一个节点的父id等于参数节点的id，则把这个节点写入参数节点的子节点list*/
        List<MenuDTO> children = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getParentId().equals(functionVO.getId())) {
                children.add(list.get(i));
            }
        }
        if (children.size() > 0) {
            /*如果子节点list中有对象存在，则用递归去寻找子节点的子节点，直到不再有子节点*/
            List<MenuDTO> param = new ArrayList<>();
            for (MenuDTO childTree : children) {
                MenuDTO grandChild = recursionChildren(childTree, list);
                param.add(grandChild);
            }
            /*最终返回传进来的带有所有functionVO = {MenuDTO@17189} "MenuDTO(id=600000300004, parentId=600000, code=ROLE_FUN_016_01, menuName=用户组管理, menuNameEn=null, menuUrl=/usergroup, orderNo=3, icon=, menuType=3, childList=[], haveChildren=false)"子节点的参数节点*/
            functionVO.setChildList(param);
            functionVO.setHaveChildren(true);
        }
        return functionVO;
    }

    /**
     * 菜单树
     *
     * @param userId
     * @param menuType
     * @return
     */
    @Override
    public List<MenuDTO> getMenuTree(String userId, Integer menuType) {
        return getMenuTree(userId, menuType, sysUserService.isAdmin(userId));
    }

    /**
     * 菜单树
     *
     * @param userId
     * @param menuType
     * @param isAdmin
     * @return
     */
    @Override
    public List<MenuDTO> getMenuTree(String userId, Integer menuType, Boolean isAdmin) {
        List<SysFunction> menuFunction;
        if (isAdmin) {
            //超级管理员
            menuFunction = sysFunctionMapper.findByMenuTreeByType(menuType);
        } else {
            menuFunction = getSysFunctions(userId, menuType, false);
        }
        List<MenuDTO> tree = functionTree(menuFunction);
        return tree;
    }

//    /**
//     * 当登录用户不是Admin的时候，返回有权限的所有功能
//     *
//     * @param userId
//     * @return
//     */
//    private List<SysFunction> getNuAdminFunction(String menuType, String userId) {
//        List<SysFunction> roleFunctions = sysFunctionMapper.getRoleFunctions(userId);
//        //单独分配的功能
//        List<SysFunction> userFunctions = sysUserFunctionMapper.getUserFunction(userId);
//
//        List<String> roleFunIds = roleFunctions.stream().map(SysFunction::getId).collect(Collectors.toList());
//        List<String> userFunIds = userFunctions.stream().map(SysFunction::getId).collect(Collectors.toList());
//        roleFunIds.addAll(userFunIds);
//        if (CollUtil.isNotEmpty(roleFunIds)) {
//            List<String> temp = roleFunIds.stream().filter(StrUtil::isNotBlank).collect(Collectors.toList());
//            QueryWrapper<SysFunction> query = new QueryWrapper<>();
//            query.in("id", temp);
//            query.eq("delete_flag", 0);
//            query.eq("menu_type", menuType);
//            query.orderByAsc("function_level, order_no");
//
//            return sysFunctionMapper.selectList(query);
//        }
//        return new ArrayList<>();
//    }

    /**
     * 获取所有的菜单记录数据
     *
     * @param menuType
     * @param userId
     * @return
     */
    @Override
    public List<SysFunction> getAllFunction(String menuType, String userId, boolean isFull) {
        boolean admin = sysUserService.isAdmin(userId);
        List<SysFunction> functions;

        Integer appMenuType = Integer.parseInt(menuType);
        if (admin) {

            //超级管理员
            QueryWrapper<SysFunction> functionQueryWrapper = new QueryWrapper<>();
            functionQueryWrapper.eq("menu_type", appMenuType);
            functionQueryWrapper.eq("delete_flag", 0);
            List<Integer> funcTypeId = Arrays.asList(1, 2);
            if (!isFull) {
                functionQueryWrapper.in("function_type", funcTypeId);
            }
            functionQueryWrapper.orderByAsc("function_level, order_no");
            functions = sysFunctionMapper.selectList(functionQueryWrapper);
        } else {
            functions = getSysFunctions(userId, appMenuType, isFull);
        }
        return functions;
    }

    /**
     * 获取所有功能编码
     *
     * @param menuType 菜单业务种类
     * @param userId   用户ID
     * @return 功能编码
     */
    @Override
    public List<String> getAllFunctionCode(String menuType, String userId) {
        List<SysFunction> functions = getAllFunction(menuType, userId, true);
        return functions.stream().filter(it -> StrUtil.isNotBlank(it.getCode())).map(SysFunction::getCode).collect(Collectors.toList());
    }

    /**
     * 获取所有的菜单权限
     *
     * @param menuType
     * @param userId
     * @return
     */
    @Override
    public List<MenuDTO> getAllMenu(String menuType, Integer urlFlag, String userId) {
        final List<SysFunction> functions = getAllFunction(menuType, userId, false);
        return getMenuDTOS(urlFlag, functions);
    }

    /**
     * 构建菜单
     *
     * @param urlFlag
     * @param functions
     * @return
     */
    private List<MenuDTO> getMenuDTOS(Integer urlFlag, List<SysFunction> functions) {
        //找到所有的菜单
        List<MenuDTO> allMenuList = functions.stream()
                .filter(it -> "1".equals(it.getFunctionType()) || "2".equals(it.getFunctionType()))
                .map(it -> {
                    final MenuDTO menuDTO = this.buildFromSysFunction(it);
                    if ("1".equals(it.getFunctionType()) && (urlFlag == null || urlFlag == 0)) {
                        menuDTO.setMenuUrl("javascript:void(0)");
                    }
                    return menuDTO;
                }).collect(Collectors.toList());
        //按父菜单分类
        Map<String, List<MenuDTO>> funcMap = allMenuList.stream().filter(it -> it.getParentId() != null)
                .collect(Collectors.groupingBy(MenuDTO::getParentId));
        //有子菜单的设置子菜单
        allMenuList.stream().filter(it -> funcMap.containsKey(it.getId()))
                .forEach(it -> {
                    it.setHaveChildren(true);
                    it.setChildList(funcMap.get(it.getId()).stream()
                            .sorted(Comparator.comparing(MenuDTO::getOrderNo))
                            .collect(Collectors.toList()));
                });
        //将第一级菜单返回
        return allMenuList.stream().filter(it -> it.getParentId() == null)
                .sorted(Comparator.comparing(MenuDTO::getOrderNo))
                .collect(Collectors.toList());
    }

    /**
     * 构建菜单
     *
     * @param urlFlag
     * @param functions
     * @return
     */
    private Map<String, Object> getMenuDTOSToMap(Integer urlFlag, List<SysFunction> functions) {
        //找到所有的菜单
        List<MenuDTO> allMenuList = functions.stream()
                .filter(it -> "1".equals(it.getFunctionType()) || "2".equals(it.getFunctionType()))
                .map(it -> {
                    final MenuDTO menuDTO = this.buildFromSysFunction(it);
                    if ("1".equals(it.getFunctionType()) && (urlFlag == null || urlFlag == 0)) {
                        menuDTO.setMenuUrl("javascript:void(0)");
                    }
                    return menuDTO;
                })
                .collect(Collectors.toList());
        //按父菜单分类
        Map<String, List<MenuDTO>> funcMap = allMenuList.stream().filter(it -> Objects.nonNull(it.getParentId()))
                .collect(Collectors.groupingBy(MenuDTO::getParentId));
        //设置是否有子菜单，不是一级菜单的，设置子菜单列表
        allMenuList.stream().filter(it -> funcMap.containsKey(it.getId()))
                .peek(it -> it.setHaveChildren(true))
                .filter(it -> Objects.nonNull(it.getParentId()))
                .forEach(it -> it.setChildList(funcMap.get(it.getId())));
        //取出第一级菜单
        List<MenuDTO> firstLevelMenuList = allMenuList.stream().filter(it -> StringUtils.isEmpty(it.getParentId())).sorted(Comparator.comparing(MenuDTO::getOrderNo)).collect(Collectors.toList());

        List<String> firstIdList = firstLevelMenuList.stream().map(MenuDTO::getId).collect(Collectors.toList());
        //组装结果
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("first", firstLevelMenuList);
        funcMap.forEach((firstId, childList) -> {
            if (firstIdList.contains(firstId)) {
                resultMap.put(firstId, childList);
                loopChildList(firstId, childList, resultMap);
            }
        });
        return resultMap;
    }

    /**
     * 遍历子数据，组装url和菜单ID
     */
    private void loopChildList(String firstId, List<MenuDTO> childList, Map<String, Object> resultMap) {
        if (CollUtil.isNotEmpty(childList)) {
            childList.forEach(it -> {
                resultMap.put(it.getMenuUrl(), firstId);
                if (it.getHaveChildren()) {
                    loopChildList(firstId, it.getChildList(), resultMap);
                }
            });
        }
    }

    /**
     * 获取业务种类对象的Logo
     *
     * @param businessTypes
     * @param orgId
     * @return
     */
    @Override
    public List<SysOrgLogoDTO> getOrgLogo(String businessTypes, String orgId) {
        List<String> types = Arrays.asList(businessTypes.split(","));
        List<SysOrgLogoDTO> orgLogoDTOS = sysOrgMapper.getOrgLogo(orgId, types);
        return orgLogoDTOS;
    }

    /**
     * 查询角色授权的功能
     *
     * @param roleIdSet 角色ID集合
     * @return 角色和功能映射，key是roleId, value是所有functionId
     */
    @Override
    public Map<String, Collection<String>> findIdByRoleId(Collection<String> roleIdSet) {
        QueryWrapper<SysRoleFunction> roleFunQuery = new QueryWrapper<>();
        roleFunQuery.in("role_id", roleIdSet);
        List<SysRoleFunction> sysRoleFunctions = sysRoleFunctionMapper.selectList(roleFunQuery);
        Map<String, Collection<String>> resultMap = new HashMap<>();
        for (Map.Entry<String, List<SysRoleFunction>> entry : sysRoleFunctions.stream()
                .collect(Collectors.groupingBy(SysRoleFunction::getRoleId)).entrySet()) {
            final Set<String> funIdSet = entry.getValue().stream().map(it -> it.getFunctionId()).collect(Collectors.toSet());
            resultMap.put(entry.getKey(), funIdSet);
        }
        return resultMap;
    }

    ///////////////////////////////////整合////////////////

//    @Resource
//    private sysRoleFunctionMapper sysRoleFunctionMapper;
//
//
//    @Resource
//    private SysRoleMapper sysRoleMapper;

    /**
     * 功能模块分页
     */
    public Map<String, Object> getSysFunctionsPage(String userId, boolean isAdmin, FunctionPageRequest functionPageRequest) {
        List<SysFunction> sysFunctionList = sysFunctionMapper.pageFunction(userId, isAdmin, functionPageRequest);
        int recordsTotal = sysFunctionMapper.countFunction(userId, isAdmin, functionPageRequest);
        Map<String, Object> resultMap = new HashMap(3);
        resultMap.put("recordsTotal", recordsTotal);
        resultMap.put("recordsFiltered", recordsTotal);
        resultMap.put("data", sysFunctionList);
        return resultMap;
    }

    /**
     * ID起始时间
     */
    private static final long START = 1691655000129L;

    /**
     * 获取功能ID
     */
    private String getFunctionId() {
        String id = "FF" + (System.currentTimeMillis() - START);
        SysFunction sysFunction = sysFunctionMapper.selectById(id);
        while (sysFunction != null) {
            id = String.valueOf(System.currentTimeMillis() - START);
            sysFunction = sysFunctionMapper.selectById(id);
        }
        return id;
    }

    /**
     * 新增菜单功能
     */
    public Map<String, SysFunction> addFunction(SysFunction sysFunction) {
        if (StrUtil.isBlank(sysFunction.getId())) {
            sysFunction.setId(getFunctionId());
        }
        Map<String, SysFunction> result = new HashMap<>();
        sysFunction.setCreateDt(DateUtil.getCurrentTime());
        sysFunction.setCode(sysFunction.getId());
        if (sysFunction.getParentId() == null || "-1".equals(sysFunction.getParentId().trim())) {
            sysFunction.setParentId(null);
            sysFunction.setFunctionLevel(String.valueOf(1));
            List<SysFunction> functionList = sysFunctionMapper.findByLevel(1);
            int orderNo = 1;
            if (functionList != null && functionList.size() != 0) {
                IntSummaryStatistics statistics = functionList.stream().mapToInt(SysFunction::getOrderNo).summaryStatistics();
                orderNo = statistics.getMax() + 1;
            }
            sysFunction.setOrderNo(orderNo);
        } else {
            //如果父功能不为空，找到父功能
            SysFunction parentFunction = sysFunctionMapper.findOneById(sysFunction.getParentId());
            sysFunction.setFunctionLevel(parentFunction.getFunctionLevel() + 1);
            result.put("parentFunction", parentFunction);
            // 设置排序
            List<SysFunction> childs = sysFunctionMapper.findByParentId(sysFunction.getParentId(), null, true);
            int orderNo = 1;
            if (childs != null && childs.size() != 0) {
                IntSummaryStatistics statistics = childs.stream().mapToInt(SysFunction::getOrderNo).summaryStatistics();
                orderNo = statistics.getMax() + 1;
            }
            sysFunction.setOrderNo(orderNo);
        }
        sysFunctionMapper.insert(sysFunction);
        result.put("function", sysFunction);
        return result;
    }

    /**
     * 修改功能
     */
    public Map<String, SysFunction> updateFunction(SysFunction sysFunction) {
        Map<String, SysFunction> result = new HashMap<>();
        sysFunction.setModifyDt(DateUtil.getCurrentDate());
        SysFunction oldFunction = sysFunctionMapper.selectById(sysFunction.getId());
        if (Objects.nonNull(oldFunction)) {
            sysFunction.setOrderNo(oldFunction.getOrderNo());
            sysFunction.setIcon(oldFunction.getIcon());
        }
        if (sysFunction.getParentId() == null || "-1".equals(sysFunction.getParentId().trim())) {
            sysFunction.setParentId(null);
            sysFunction.setFunctionLevel(String.valueOf(1));
        } else {
            //如果父功能不为空，找到父功能
            SysFunction parentFunction = sysFunctionMapper.findOneById(sysFunction.getParentId());
            sysFunction.setFunctionLevel(Objects.toString(Integer.parseInt(parentFunction.getFunctionLevel()) + 1));
        }
        sysFunctionMapper.updateFunction(sysFunction);
        result.put("function", sysFunction);
        return result;
    }

    /**
     * 通过ID查找功能
     */
    public SysFunction findById(String id) {
        return sysFunctionMapper.findOneById(id);
    }

    /**
     * 获取当前用户功能tree结构
     *
     * @param isAdmin
     * @param userId
     * @return
     */
    public List<ZTreeBo> getFunctionsTree(boolean isAdmin, String userId) {
        List<SysFunction> sysFunctionList = sysFunctionMapper.findByUserId(isAdmin, userId, null);
        List<ZTreeBo> zTreeBos = new ArrayList<>();
        boolean isRoot = false;
        for (SysFunction sysFunction : sysFunctionList) {
            ZTreeBo bo = new ZTreeBo();
            bo.setId(sysFunction.getId());
            bo.setName(sysFunction.getFunctionName());
            bo.setOpen(false);
            if (sysFunction.getParentId() == null) {
                bo.setpId("-1");
                isRoot = true;
            } else {
                bo.setpId(sysFunction.getParentId());
            }
            bo.setType(sysFunction.getFunctionType());
            zTreeBos.add(bo);
        }
        if (isRoot) {//非admin用户进入时，功能树也显示root节点  &&isAdmin) {
            ZTreeBo bo = new ZTreeBo();
            bo.setId("-1");
            bo.setName("根目录");
            bo.setOpen(true);
            bo.setpId(null);
            zTreeBos.add(bo);
        }
        return zTreeBos;
    }

    /**
     * 获取当前用户功能tree结构
     *
     * @return
     */
    @Override
    public List<SysFunctionDTO.SysFunctionDTOTree> getFunctionsTreeV2(Integer menuType) {
        List<SysFunction> functionList = sysFunctionMapper.findByMenuType(menuType);
//        if (menuType != null) {
//            functionList = functionList.stream().filter(it -> menuType.equals(it.getMenuType())).collect(Collectors.toList());
//        }
        //转前端需要的树结构对象
        List<SysFunctionDTO.SysFunctionDTOTree> treeList = functionList.stream().map(it -> {
            SysFunctionDTO.SysFunctionDTOTree functionDTOTree = new SysFunctionDTO.SysFunctionDTOTree();
            functionDTOTree.setId(it.getId());
            functionDTOTree.setParentId(it.getParentId());
            functionDTOTree.setState(it.getDeleteFlag());
            functionDTOTree.setLabel(it.getFunctionName());
            functionDTOTree.setOrderNum(it.getOrderNo());
            return functionDTOTree;
        }).collect(Collectors.toList());
        //所有有父分类的，按父分类分组
        Map<String, List<SysFunctionDTO.SysFunctionDTOTree>> parentMap = treeList.stream()
                .filter(it -> StrUtil.isNotBlank(it.getParentId()))
                .collect(Collectors.groupingBy(SysFunctionDTO.SysFunctionDTOTree::getParentId));
        //每个节点添加上子节点
        treeList.forEach(it -> {
            it.setChildren(parentMap.getOrDefault(it.getId(), Collections.emptyList())
                    .stream().sorted(Comparator.comparingInt(SysFunctionDTO.SysFunctionDTOTree::getOrderNum))
                    .collect(Collectors.toList()));
        });
        //只保留一级节点返回
        return treeList.stream().filter(it -> StrUtil.isBlank(it.getParentId()))
                .sorted(Comparator.comparingInt(SysFunctionDTO.SysFunctionDTOTree::getOrderNum))
                .collect(Collectors.toList());
    }

    /**
     * 获取指定角色对应的功能列表
     *
     * @param roleId
     * @return
     */
    public List<SysFunction> getFunsByRoleId(String roleId) {
        return sysRoleFunctionMapper.findFunsByRoleId(roleId);
    }

    /**
     * 通过CODE统计模块数量
     */
    public int getCountByCode(String code, String ignoreId) {
        return sysFunctionMapper.countByCodeIgnoreId(code, ignoreId);
    }

    /**
     * 通过父模块ID获取模块信息
     */
    public List<ZTreeBo> getFunctionsByParentID(String parentId, String loginUserId, boolean isAdmin) {
        List<SysFunction> list = sysFunctionMapper.findByParentId(parentId, loginUserId, isAdmin);
        List<ZTreeBo> lbo = new ArrayList<ZTreeBo>();
        ZTreeBo zTreeBo = null;
        for (SysFunction sf : list) {
            zTreeBo = new ZTreeBo();
            zTreeBo.setId(sf.getId());
            zTreeBo.setpId(sf.getParentId());
            zTreeBo.setName(sf.getFunctionName());
            zTreeBo.setIsParent(true);
            lbo.add(zTreeBo);
        }
        return lbo;
    }

    /**
     * 查询子权限
     */
    public List<SysFunction> findChild(String parentId) {
        return sysFunctionMapper.findChild(parentId);
    }

    /**
     * 删除功能模块相关信息
     *
     * @param funId
     * @return
     */
    @Transactional
    public void deleteFunction(String funId) {
        List<String> childList = sysFunctionMapper.findCountByParentId(funId);
        if (childList != null && childList.size() > 0) {
            for (String functionId : childList) {
                deleteFunction(functionId);
            }
        }
        //删除功能
        sysFunctionMapper.deleteById(funId);
        //删除角色功能
        sysRoleFunctionMapper.deleteByFunctionIds(Collections.singletonList(funId));
    }

    @Transactional
    public void deleteBusiFuncForce(Integer menuType) {
        List<SysFunction> sysFunctionList = sysFunctionMapper.selectByMap(ImmutableMap.of("menu_type", menuType));
        if (CollUtil.isNotEmpty(sysFunctionList)) {
            List<String> funIds = sysFunctionList.stream().map(SysFunction::getId).collect(Collectors.toList());
            sysRoleFunctionMapper.deleteByFunctionIds(funIds);// 角色--功能

            QueryWrapper<SysUserFunction> userFunction = new QueryWrapper<>();
            userFunction.in("function_id", funIds);
            sysUserFunctionMapper.delete(userFunction); // 用户--功能

            QueryWrapper<SysOrderFunction> orderFunction = new QueryWrapper<>();
            orderFunction.in("function_id", funIds);
            sysOrderFunctionMapper.delete(orderFunction);   //订单--功能

            QueryWrapper<SysFunction> function = new QueryWrapper<>();
            function.in("id", funIds);
            sysFunctionMapper.delete(function); //删除功能
        }
    }

    /**
     * 功能模块关联处理
     */
    public Map<String, Object> getFunRelation(String functionId) {
        Map<String, Object> map = new HashMap<>();
        List<SysRole> sysRoleDTOList = sysRoleMapper.findRolesByFunctionId(functionId);
        map.put("roles", sysRoleDTOList);
        map.put("groups", null);
        map.put("users", null);
        return map;
    }

    public void updateOrderNo(SysFunction.RequestOrderParam requestOrderParam, String userId) {
        requestOrderParam.getFunctionList().forEach(it -> {
            sysFunctionMapper.updateOrderNo(it.getFunctionId(), it.getOrderNo(), userId, DateUtil.getCurrentDate());
        });
    }

    public void enableOrDisable(SysFunction.RequestEnableParam requestOrderParam, String userId) {
        requestOrderParam.getFunctionList().forEach(it -> {
            sysFunctionMapper.enableOrDisable(it.getFunctionId(), it.getDeleteFlag(), userId, DateUtil.getCurrentDate());
        });
    }


}
